﻿using static WebApi2.HostedServices.MqttService;

namespace WebApi2.HostedServices
{
    public class MqttHostService(ILogger<MqttHostService> logger) : BackgroundService
    {
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var optionsBilder = new MqttServerOptionsBuilder();
            optionsBilder.WithDefaultEndpoint().WithDefaultEndpointPort(5005);

            var options = optionsBilder.Build();
            _mqttServer = new MqttFactory().CreateMqttServer(options);
            _mqttServer.ClientConnectedAsync += _mqttServer_ClientConnectedAsync;
            _mqttServer.ClientDisconnectedAsync += _mqttServer_ClientDisconnectedAsync;
            _mqttServer.ApplicationMessageNotConsumedAsync += _mqttServer_ApplicationMessageNotConsumedAsync;

            _mqttServer.ClientSubscribedTopicAsync += _mqttServer_ClientSubscribedTopicAsync;
            _mqttServer.ClientUnsubscribedTopicAsync += _mqttServer_ClientUnsubscribedTopicAsync;
            _mqttServer.StartedAsync += _mqttServer_StartedAsync;
            _mqttServer.StoppedAsync += _mqttServer_StoppedAsync;
            _mqttServer.InterceptingPublishAsync += _mqttServer_InterceptingPublishAsync;
            _mqttServer.ValidatingConnectionAsync += _mqttServer_ValidatingConnectionAsync;
            _mqttServer.StartAsync();
            await Task.Delay(10000);
        }

        private Task _mqttServer_ValidatingConnectionAsync(ValidatingConnectionEventArgs arg)
        {
            arg.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.Success;
            if ((arg.Username ?? string.Empty) != "admin" || (arg.Password ?? string.Empty) != "123456")
            {
                arg.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.Banned;
                Console.WriteLine($"ValidationConnectionAsync:客户端ID【{arg.ClientId}】用户名或密码验证错误");
            }
            return Task.CompletedTask;
        }

        private Task _mqttServer_InterceptingPublishAsync(InterceptingPublishEventArgs arg)
        {
            Console.WriteLine($"InterceptingPublishAsync: 客户端ID=【{arg.ClientId}】，Topic主题=【{arg.ApplicationMessage.Topic}】，消息=【{Encoding.UTF8.GetString(arg.ApplicationMessage.Payload)}】，qos等级=【{arg.ApplicationMessage.QualityOfServiceLevel}】");
            return Task.CompletedTask;
        }

        private Task _mqttServer_StoppedAsync(EventArgs arg)
        {
            Console.WriteLine($"StopedAsync: MQTT服务已关闭……");
            return Task.CompletedTask;
        }

        private Task _mqttServer_StartedAsync(EventArgs arg)
        {
            logger.LogInformation($"StatedAsync: MQTT服务已启动……");
            return Task.CompletedTask;
        }

        private Task _mqttServer_ClientUnsubscribedTopicAsync(ClientUnsubscribedTopicEventArgs arg)
        {
            Console.WriteLine($"ClientUnsubscribedTopicAsync: 客户端ID=【{arg.ClientId}】， 已取消订阅的主题=【{arg.TopicFilter}】");
            return Task.CompletedTask;
        }

        private Task _mqttServer_ClientSubscribedTopicAsync(ClientSubscribedTopicEventArgs arg)
        {
            Console.WriteLine($"ClientSubscribedTopicAsync:客户端ID=【{arg.ClientId}】，订阅的主题=【{arg.TopicFilter}】");
            return Task.CompletedTask;
        }

        private Task _mqttServer_ApplicationMessageNotConsumedAsync(ApplicationMessageNotConsumedEventArgs arg)
        {
            Console.WriteLine($"ApplicationMessageNotConsumedAsync: 发送端ID=【{arg.SenderId}】，Topic主题=【{arg.ApplicationMessage.Topic}】， 消息=【{Encoding.UTF8.GetString(arg.ApplicationMessage.Payload)}】，qos等级=【{arg.ApplicationMessage.QualityOfServiceLevel}】");
            return Task.CompletedTask;
        }

        private Task _mqttServer_ClientDisconnectedAsync(ClientDisconnectedEventArgs args)
        {
            Console.WriteLine($"客户端ID=【{args.ClientId}】已断开，地址=【{args.Endpoint}】");
            return Task.CompletedTask;
        }

        Task _mqttServer_ClientConnectedAsync(ClientConnectedEventArgs args)
        {
            Console.WriteLine($"客户端ID=【{args.ClientId}】已连接，用户名=【{args.UserName}】，地址=【{args.Endpoint}】");
            return Task.CompletedTask;
        }
    }
    public class MqttService
    {
        public static MqttServer? _mqttServer { get; set; }
        public static async Task PublishData(string data)
        {
            if ( _mqttServer == null ) { return; }
            var message = new MqttApplicationMessage
            {
                Topic = "topic_01",
                Payload = Encoding.Default.GetBytes(data),
                QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce,
                Retain = true,
            };
            await _mqttServer.InjectApplicationMessage(new InjectedMqttApplicationMessage(message)
            {
                SenderClientId="Server_01"
            });
        }
    }
}
